package ca;

import java.util.ArrayList;

public class BeliefSpace {
	private NormativeComponent normativeComponent;
	private SituationalComponent situationalComponent;
	private DomainComponent domainComponent;
	private int numberSituationalIndividuals;
	private double[][] accepptedIndividuals;
	private double[] fitnessAccepptedIndividuals;
	
	public BeliefSpace(int nSituationalsIndividuals, int nParameters) {
		normativeComponent = new NormativeComponent(nParameters);
		situationalComponent = new SituationalComponent(nSituationalsIndividuals, nParameters);
		domainComponent = new DomainComponent(nParameters);
		this.numberSituationalIndividuals = nSituationalsIndividuals;
	}
	
	public NormativeComponent getNormativeComponent() {
		return normativeComponent;
	}

	public SituationalComponent getSituationalComponent() {
		return situationalComponent;
	}

	public void accept(double[][] individuals, double[] fitness){
		accepptedIndividuals = new double[numberSituationalIndividuals][individuals[0].length];
		fitnessAccepptedIndividuals = new double[individuals[0].length];
		
		ArrayList<Integer> indexesAccepted = new ArrayList<Integer>(numberSituationalIndividuals);
		ArrayList<Double> fitnessAccepted = new ArrayList<Double>(numberSituationalIndividuals);
		
		for(int i = 0; i < numberSituationalIndividuals; i++){
			fitnessAccepted.set(i,fitness[i]);
			indexesAccepted.set(i,i);
		}
		
		for(int i = 0; i < fitness.length; i++){
			for(int j = 0; j < numberSituationalIndividuals; j++){
				if(fitness[i] < fitnessAccepted.get(j)){
					indexesAccepted.set(j,i);
					fitnessAccepted.set(j,fitness[i]);
					break;
				}
			}
		}
		
		for(int i = 0; i < numberSituationalIndividuals; i++){
			for(int k = 0; k < individuals[0].length; k++){
				accepptedIndividuals[i][k] = individuals[indexesAccepted.get(i)][k];
				fitnessAccepptedIndividuals[k] = fitness[indexesAccepted.get(i)];
			}
		}
	}
	
	public void adjustBeliefSpace(){
//		accept(individuals, fitness);
		situationalComponent.adjustSpace(accepptedIndividuals, fitnessAccepptedIndividuals);
		normativeComponent.adjustSpace(accepptedIndividuals, fitnessAccepptedIndividuals);
	}

	public void setDomainDimension(int dimension, double min, double max) {
		domainComponent.setDimension(dimension, min, max);
	}
	
	
	public void setNormativeDimension(int dimension, double min, double max, double fitnessMin, double fitnessMax) {
		normativeComponent.setDimension(dimension, min, max, fitnessMin, fitnessMax);
	}

	public void initSituationalComponent() {
		situationalComponent.setIndividualFitness(this.fitnessAccepptedIndividuals);
		situationalComponent.setIndividuals(this.accepptedIndividuals);
	}
}
